// Copyright 2023 Srhino Co., Ltd. All rights reserved.

package discovery

import (
	"regexp"
	"strings"
)

// Match 规则匹配
func (dr *DiscoverRule) Match(resq *ApiRequest) bool {

	if dr.MatchRequestMethod(resq.Method) && dr.MatchResponseCode(resq.ResponseCode) && dr.MatchRequestURL(resq.URL) &&
		dr.MatchRequestHeaders(resq.RequestHeaders) && dr.MatchResponseHeaders(resq.ResponseHeaders) {

		return true
	}

	return false
}

// MatchRequestMethod method 校验
func (dr *DiscoverRule) MatchRequestMethod(method string) bool {
	if len(dr.RequestHeader.Method) > 0 {
		for i, m := range dr.RequestHeader.Method {
			if strings.ToLower(m) == strings.ToLower(method) {
				break
			} else {
				if i == len(dr.RequestHeader.Method)-1 {
					return false
				}
			}
		}
	}
	return true
}

// MatchRequestURL URL 校验
func (dr *DiscoverRule) MatchRequestURL(url string) bool {
	if len(dr.RequestHeader.URL) > 0 {
		for i, u := range dr.RequestHeader.URL {
			reg, err := regexp.Compile(u)
			if err != nil {
				if i == len(dr.RequestHeader.URL)-1 {
					return false
				}
				continue
			}

			if reg.MatchString(url) {
				break
			} else {
				if i == len(dr.RequestHeader.URL)-1 {
					return false
				}
			}
		}
	}
	return true
}

// MatchResponseCode 校验 response code
func (dr *DiscoverRule) MatchResponseCode(code uint32) bool {
	// ResponseCode 校验
	if len(dr.ResponseHeader.IgnoreResponseCode) > 0 {
		l := len(dr.ResponseHeader.IgnoreResponseCode)

		if l == 2 {
			if code >= dr.ResponseHeader.IgnoreResponseCode[0] && code < dr.ResponseHeader.IgnoreResponseCode[1] {
				return false
			}
		} else {
			for _, ic := range dr.ResponseHeader.IgnoreResponseCode {
				if ic == code {
					return false
				}
			}
		}
	}
	return true
}

// MatchRequestHeaders 校验 request headers
func (dr *DiscoverRule) MatchRequestHeaders(resqH ApiRequestHeaders) bool {
	// Accept 校验
	if len(dr.RequestHeader.Accept) > 0 {
		for i, a := range dr.RequestHeader.Accept {
			reg, err := regexp.Compile(a)
			if err != nil {
				if i == len(dr.RequestHeader.Accept)-1 {
					return false
				}
				continue
			}

			if reg.MatchString(resqH.Accept) {
				break
			} else {
				if i == len(dr.RequestHeader.Accept)-1 {
					return false
				}
			}
		}
	}

	// ContentType 校验
	if len(dr.RequestHeader.ContentType) > 0 {
		for i, c := range dr.RequestHeader.ContentType {
			reg, err := regexp.Compile(c)
			if err != nil {
				if i == len(dr.RequestHeader.ContentType)-1 {
					return false
				}
				continue
			}

			if reg.MatchString(resqH.ContentType) {
				break
			} else {
				if i == len(dr.RequestHeader.ContentType)-1 {
					return false
				}
			}
		}
	}

	return true
}

// MatchResponseHeaders 校验 response headers
func (dr *DiscoverRule) MatchResponseHeaders(respH ApiResponseHeaders) bool {

	// ContentType 校验
	if len(dr.ResponseHeader.ContentType) > 0 {
		for i, c := range dr.ResponseHeader.ContentType {
			reg, err := regexp.Compile(c)
			if err != nil {
				if i == len(dr.ResponseHeader.ContentType)-1 {
					return false
				}
				continue
			}

			if reg.MatchString(respH.ContentType) {
				break
			} else {
				if i == len(dr.ResponseHeader.ContentType)-1 {
					return false
				}
			}
		}
	}
	return true
}
